package com.duobeiyun.gmstest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Observer;
import androidx.work.Data;
import androidx.work.ExistingWorkPolicy;
import androidx.work.ListenableWorker;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkContinuation;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.duobeiyun.gmstest.file.FIleManager;
import com.duobeiyun.gmstest.log.LogConsole;
import com.duobeiyun.gmstest.log.LogFile;
import com.duobeiyun.gmstest.log.LogInterface;
import com.duobeiyun.gmstest.log.LogOuter;
import com.duobeiyun.gmstest.log.LogScreen;
import com.duobeiyun.gmstest.work.WorkAcceptTest;
import com.duobeiyun.gmstest.work.WorkCheckConnectState;
import com.duobeiyun.gmstest.work.WorkConnectStateByToken;
import com.duobeiyun.gmstest.work.WorkJoinChannel;
import com.duobeiyun.gmstest.work.WorkLoginTest;
import com.duobeiyun.gmstest.work.WorkOne;
import com.duobeiyun.gmstest.work.WorkPeerOnLineStatus;
import com.duobeiyun.gmstest.work.WorkSendChannelMessage;
import com.duobeiyun.gmstest.work.WorkSetChannelAttributes;
import com.duobeiyun.gmstest.work.WorkUnsubscribePeerOnLineStatus;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unchecked")
public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    private static final String[] PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private static final int PERMISSION_CODE = 1000;

    private ArrayList<String> deniedPermission = new ArrayList<>();
    private TextView logScreenTV;
    //    private RadioGroup radioGroup;
    private LogScreen logScreen;
    private CheckBox outConsole;
    private CheckBox outScreen;
    private CheckBox outFile;
    private WorkManager workManager;

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_CODE) {
            deniedPermission.clear();
            for (int i = 0; i < permissions.length; i++) {
                String permission = permissions[i];
                int result = grantResults[i];
                if (result != PackageManager.PERMISSION_GRANTED) {
                    deniedPermission.add(permission);
                }
            }


            if (deniedPermission.isEmpty()) {
                FIleManager.create(this);
            } else {
                new AlertDialog.Builder(this)
                        .setMessage("请重新授权")
                        .setNegativeButton("不", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                MainActivity.this.finish();
                            }
                        })
                        .setPositiveButton("好", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                String[] denied = new String[deniedPermission.size()];
                                ActivityCompat.requestPermissions(MainActivity.this, deniedPermission.toArray(denied), PERMISSION_CODE);
                            }
                        }).create().show();
            }
        }
    }


    private static final String TAG = "MainActivity";
    static final String MANIPULATION_WORK_NAME = "image_manipulation_work";
    private OneTimeWorkRequest oneTimeWorkRequest;
    private TextView input_number;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_CODE);
        setContentView(R.layout.activity_main);
        input_number = findViewById(R.id.input_number);
        logScreenTV = findViewById(R.id.log_screen);
//        radioGroup = ((RadioGroup) findViewById(R.id.logout_select));
        outConsole = findViewById(R.id.out_console);
        outScreen = findViewById(R.id.out_screen);
        outFile = findViewById(R.id.out_file);
        FIleManager.create(this);
        gmsRegistered();

        outputModeByCheck();

    }


    /**
     * 选择输出模式
     * out_console:输出控制台
     * out_screen:输出到屏幕
     * out_file:输出到文件
     * 文件路径为android缓存路径,一般为:android/data/com.duobeiyun.gmstest/cache/dby_gms_test.txt
     */
    private void outputModeByCheck() {
        logScreen = new LogScreen();
        LogConsole logConsole = new LogConsole();
        LogFile logFile = new LogFile();
//        final LogInterface outerLogInterface = logConsole;
//        LogOuter.setLogInterface(outerLogInterface);
//        radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
//            Log.d(TAG, "onCheckedChanged: group:" + group + " checkedId:" + checkedId);
//            LogInterface logInterface = outerLogInterface;
//            switch (checkedId) {
//                case R.id.out_console:
//                    logInterface = logConsole;
//                    break;
//
//                case R.id.out_screen:
//                    logInterface = logScreen;
//                    break;
//
//                case R.id.out_file:
//                    logInterface = logFile;
//                    break;
//            }
//            LogOuter.setLogInterface(logInterface);
//        });
        LogOuter.setConsoleLogInterface(logConsole);
        LogOuter.setScreenLogInterface(logScreen);
        LogOuter.setFileLogInterface(logFile);

        outConsole.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    LogOuter.setConsoleLogInterface(logConsole);
                } else {
                    LogOuter.setConsoleLogInterface(null);
                }
            }
        });

        outScreen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    LogOuter.setScreenLogInterface(logScreen);
                } else {
                    LogOuter.setScreenLogInterface(null);
                }
            }
        });

        outFile.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    LogOuter.setFileLogInterface(logFile);
                } else {
                    LogOuter.setFileLogInterface(null);
                }
            }
        });


    }

    /**
     * gms的初始化工作,实现为 {@link WorkOne}
     */
    private void gmsRegistered() {
        Data inputData = new Data.Builder().putString("time", "...").build();
        oneTimeWorkRequest = getOneTimeWorkRequest(inputData, WorkOne.class);

        ArrayList<OneTimeWorkRequest> oneTimeWorkRequests = new ArrayList<>();
        oneTimeWorkRequests.add(oneTimeWorkRequest);
        enqueue(oneTimeWorkRequests);
        allRequest.clear();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        FIleManager.close();
    }

    List<OneTimeWorkRequest> allRequest = new ArrayList<>();

    /**
     * 生成指定用例的测试请求
     *
     * @param inputData
     * @param clazz
     * @return
     */
    private OneTimeWorkRequest getOneTimeWorkRequest(Data inputData, Class<? extends ListenableWorker> clazz) {
        OneTimeWorkRequest request = new OneTimeWorkRequest
                .Builder(clazz)
                .setInputData(inputData)
                .build();
        allRequest.add(request);
        return request;
    }

    private void enqueue(List<OneTimeWorkRequest> workRequests, OneTimeWorkRequest... requests) {
        workManager = WorkManager.
                getInstance(this);
        WorkContinuation workContinuation = null;
        int i = 0;
        if (workRequests == null) {
            workContinuation = workManager.beginUniqueWork(MANIPULATION_WORK_NAME, ExistingWorkPolicy.REPLACE, requests[0]);
            i = 1;
        } else {
            workContinuation = workManager.beginUniqueWork(MANIPULATION_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequests);
        }

        for (; i < requests.length; i++) {
            workContinuation = workContinuation.then(requests[i]);
        }
        workContinuation.enqueue();

//        workContinuation.getWorkInfosLiveData().observe(this, workInfos -> {
//            Log.d(TAG, "print:onChanged: " + workInfos);
//        });


    }

    /**
     * 生成测试用例
     *
     * @param chooseNumber 选择运行指定的用例,用编号标识,使用空格进行分割
     */
    private void generateRequest(String chooseNumber) {
        OneTimeWorkRequest lastRequest;
        for (Class<? extends ListenableWorker> aClass : clazz) {
            Data data;
            if (chooseNumber.equals("all")) {
                data = new Data.Builder().putBoolean("chose_all", true).build();
            } else {
                String[] number = chooseNumber.split(" ");
                data = new Data.Builder().putStringArray("chose_number", number).build();
            }
            lastRequest = getOneTimeWorkRequest(data, aClass);
        }

        if (outScreen.isChecked()) {
            for (int i = 0; i < allRequest.size(); i++) {
                OneTimeWorkRequest request = allRequest.get(i);
                WorkManager.getInstance().getWorkInfoByIdLiveData(request.getId()).observe(this, workInfo -> {
                    if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                        logScreenTV.setText(logScreen.getSb().toString());
                    }
                    Log.d(TAG, "print:last onChanged: " + workInfo);
                });
            }

        }

        enqueue(null, allRequest.toArray(new OneTimeWorkRequest[0]));

    }


    /**
     * 所有的用例数组
     */
    Class<? extends ListenableWorker>[] clazz = new Class[]{

            WorkLoginTest.class,
            WorkPeerOnLineStatus.class,
            WorkUnsubscribePeerOnLineStatus.class,
            WorkJoinChannel.class,
            WorkSendChannelMessage.class,
            WorkSetChannelAttributes.class,
            WorkAcceptTest.class,
            WorkCheckConnectState.class,
            WorkConnectStateByToken.class,
    };

    /**
     * 点击事件:测试指定用例
     *
     * @param view
     */
    public void testSub(View view) {
        if (workManager != null) {
            workManager.cancelUniqueWork(MANIPULATION_WORK_NAME);
        }
        hideInput(view);
        logScreenTV.setText("");
        logScreen.getSb().setLength(0);

        String s = input_number.getText().toString();
        allRequest.clear();
        generateRequest(s);

    }

    /**
     * 点击事件:测试所有用例
     *
     * @param view
     */
    public void testAll(View view) {
        if (workManager != null) {
            workManager.cancelUniqueWork(MANIPULATION_WORK_NAME);
        }
        hideInput(view);
        logScreenTV.setText("");
        logScreen.getSb().setLength(0);

        allRequest.clear();
        generateRequest("all");
    }

    void hideInput(View v) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
}
